package com.settlement.system.controller;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.settlement.system.common.annotation.PreventDuplicateSubmit;
import com.settlement.system.common.constant.SystemConstants;
import com.settlement.system.common.model.Option;
import com.settlement.system.common.result.PageResult;
import com.settlement.system.common.result.Result;
import com.settlement.system.common.util.EasyExcelImportUtils;
import com.settlement.system.common.util.StringUtils;
import com.settlement.system.model.entity.SysAccessory;
import com.settlement.system.model.entity.SysAccountingProject;
import com.settlement.system.model.form.AccountProjectForm;
import com.settlement.system.model.query.AccountingProjectPageQuery;
import com.settlement.system.model.vo.SysAccountingProjectVO;
import com.settlement.system.service.SysAccessoryService;
import com.settlement.system.service.SysAccountingProjectService;
import com.settlement.system.service.SysDictService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * <p>
 * 记账项目配置 前端控制器
 * </p>
 *
 * @author huangrensen
 * @since 2023-09-08
 */
@Tag(name = "记账项目配置")
@RestController
@RequestMapping("/api/v1/accountingProject")
@RequiredArgsConstructor
public class SysAccountingProjectController {

    private final SysAccountingProjectService sysAccountingProjectService;

    private final SysAccessoryService sysAccessoryService;

    private final SysDictService dictService;

    @Operation(summary = "记账项目配置分页列表", security = {@SecurityRequirement(name = "Authorization")})
    @GetMapping("/page")
    public PageResult<SysAccountingProjectVO> getPage(@ParameterObject AccountingProjectPageQuery queryParams) {
        Page<SysAccountingProjectVO> result = sysAccountingProjectService.getPage(queryParams);
        return PageResult.success(result);
    }

    @Operation(summary = "保存记账项目配置", security = {@SecurityRequirement(name = "Authorization")})
    @PostMapping
    @PreAuthorize("@ss.hasPerm('sys:accountingProject:save')")
    @PreventDuplicateSubmit
    public Result<?> saveAccountingProject(@RequestBody @Valid AccountProjectForm accountProjectForm) {
        boolean result = sysAccountingProjectService.saveAccountingProject(accountProjectForm);
        return Result.judge(result);
    }

    @Operation(summary = "记账项目配置单数据", security = {@SecurityRequirement(name = "Authorization")})
    @GetMapping("/{accountingProjectId}/form")
    public Result<SysAccountingProjectVO> getAccountingProjectForm(@Parameter(description = "科目表ID") @PathVariable Long accountingProjectId) {
        SysAccountingProjectVO accountingProject = sysAccountingProjectService.getSysAccountingProjectFormData(accountingProjectId);
        return Result.success(accountingProject);
    }

    @Operation(summary = "删除记账项目配置", security = {@SecurityRequirement(name = "Authorization")})
    @DeleteMapping("/{ids}")
    @PreAuthorize("@ss.hasPerm('sys:accountingProject:delete')")
    public Result<?> deleteAccountingProject(@Parameter(description = "记账项目配置ID，多个以英文逗号(,)分割") @PathVariable String ids) {
        boolean result = sysAccountingProjectService.deleteAccountingProject(ids);
        return Result.judge(result);
    }

    @Operation(summary = "导出科目", security = {@SecurityRequirement(name = "Authorization")})
    @GetMapping("/_export")
    public void export(HttpServletResponse response, @RequestParam String ids) throws IOException {
        String fileName = "记账项目表.xlsx";
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setHeader("Content-Disposition", "attachment; filename=" + URLEncoder.encode(fileName, StandardCharsets.UTF_8));
        // 设置动态头
        List<List<String>> headList = new ArrayList<>();
        // 默认表头
        List<String> defaultHead = SysAccountingProject.excelHeader();
        // 辅助项表头
        List<SysAccessory> accessoryList = sysAccessoryService.findAll();
        List<SysAccountingProjectVO> projectVOList = sysAccountingProjectService.getList(ids);
        // 发生方
        for (String headName : defaultHead) {
            List<String> head = new ArrayList<>();
            head.add(headName);
            headList.add(head);
        }
        List<Option> optionList = dictService.listDictOptions(SystemConstants.FUNDING_PROJECT);
        for (Option option : optionList) {
            List<String> head = new ArrayList<>();
            head.add(option.getLabel());
            headList.add(head);
        }
        List<List<String>> data = new ArrayList<>();
        List<String> item;
        for (SysAccountingProjectVO sysAccountingProjectVO : projectVOList) {
            item = new ArrayList<>();
            // 业务平台
            item.add(StringUtils.getString(sysAccountingProjectVO.getBillSystemPlatformName(), ""));
            // 来源单据
            item.add(StringUtils.getString(sysAccountingProjectVO.getOrderType(), ""));
            // 电商平台账单项目
            item.add(StringUtils.getString(sysAccountingProjectVO.getAccountingProjectName(), ""));
            // 收支方向
            item.add(StringUtils.getString(sysAccountingProjectVO.getPayType(), ""));
            // 末级科目编码
            item.add(StringUtils.getString(sysAccountingProjectVO.getLastCode(), ""));
            // 对方末级科目编码
            item.add(StringUtils.getString(sysAccountingProjectVO.getOtherLastCode(), ""));
            // 是否分摊
            item.add(StringUtils.getString(sysAccountingProjectVO.getApportionment(), ""));
            // 票前票后
            item.add(StringUtils.getString(sysAccountingProjectVO.getInvoice(), ""));
            // 稽核标识
            item.add(StringUtils.getString(sysAccountingProjectVO.getAudit(), ""));
            // 是否参与记账
            item.add(StringUtils.getString(sysAccountingProjectVO.getAccounting(), ""));
            // 供应商名称
            item.add(StringUtils.getString(sysAccountingProjectVO.getCarrier(), ""));
            // 借贷方向
            item.add(StringUtils.getString(sysAccountingProjectVO.getBorrowing(), ""));
            // 对方借贷方向
            item.add(StringUtils.getString(sysAccountingProjectVO.getOtherBorrowing(), ""));
            // 税率
            item.add(StringUtils.getString(sysAccountingProjectVO.getRate(), ""));
            // 资金项目计算方向
            // item.add(StringUtils.getString(sysAccountingProjectVO.getFundingDirection(), ""));
            for (Option option : optionList) {
                item.add(StringUtils.getString(sysAccountingProjectVO.getFundingProjects().get(option.getLabel()), ""));
            }
            data.add(item);
        }
        // 辅助项的数据
        List<List<String>> accessoryHeadList = new ArrayList<>();
        List<String> head = new ArrayList<>();
        head.add("业务平台");
        accessoryHeadList.add(head);
        head = new ArrayList<>();
        head.add("电商平台账单项目");
        accessoryHeadList.add(head);
        head = new ArrayList<>();
        head.add("电商平台店铺名称");
        accessoryHeadList.add(head);
        if (accessoryList.size() > 0) {
            SysAccessory sysAccessory = accessoryList.get(0);
            if (StringUtils.hasText(sysAccessory.getAccessoryName1())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName1());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName1());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName2())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName2());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName2());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName3())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName3());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName3());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName4())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName4());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName4());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName5())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName5());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName5());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName6())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName6());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName6());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName7())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName7());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName7());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName8())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName8());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName8());
                accessoryHeadList.add(head);
            }
            if (StringUtils.hasText(sysAccessory.getAccessoryName9())) {
                head = new ArrayList<>();
                head.add(sysAccessory.getAccessoryName9());
                accessoryHeadList.add(head);
                // 对方
                head = new ArrayList<>();
                head.add("对方" + sysAccessory.getAccessoryName9());
                accessoryHeadList.add(head);
            }
        }
        List<List<String>> dataAccessory = new ArrayList<>();
        Map<String, String> mapAccessoryItem;
        Map<String, String> mapOtherAccessoryItem;
        for (SysAccountingProjectVO sysAccountingProjectVO : projectVOList) {
            Set<String> storeNameSet = sysAccountingProjectVO.getAccessory().keySet();
            for (String storeName : storeNameSet) {
                mapAccessoryItem = sysAccountingProjectVO.getAccessory().get(storeName);
                if(Objects.isNull(mapAccessoryItem)){
                    mapAccessoryItem = new HashMap<>();
                }
                mapOtherAccessoryItem = sysAccountingProjectVO.getOtherAccessory().get(storeName);
                if(Objects.isNull(mapOtherAccessoryItem)){
                    mapOtherAccessoryItem = new HashMap<>();
                }
                item = new ArrayList<>();
                // 业务平台
                item.add(StringUtils.getString(sysAccountingProjectVO.getBillSystemPlatformName(), ""));
                // 电商平台账单项目
                item.add(StringUtils.getString(sysAccountingProjectVO.getAccountingProjectName(), ""));
                // 店铺
                item.add(storeName);
                SysAccessory sysAccessory = accessoryList.get(0);
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName1()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName1()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName2()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName2()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName3()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName3()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName4()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName4()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName5()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName5()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName6()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName6()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName7()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName7()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName8()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName8()), ""));
                item.add(StringUtils.getString(mapAccessoryItem.get(sysAccessory.getAccessoryName9()), ""));
                item.add(StringUtils.getString(mapOtherAccessoryItem.get(sysAccessory.getAccessoryName9()), ""));
                dataAccessory.add(item);
            }
        }
        //新建ExcelWriter
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
        WriteSheet writeSheet = EasyExcel.writerSheet("记账项目表").head(headList).build();
        excelWriter.write(data, writeSheet);
        writeSheet = EasyExcel.writerSheet("辅助项").head(accessoryHeadList).build();
        excelWriter.write(dataAccessory, writeSheet);
        excelWriter.finish();
    }


    @Operation(summary = "导入记账项目", security = {@SecurityRequirement(name = "Authorization")})
    @PostMapping("/_import")
    public Result<?> subjectsImport(@RequestParam("file") MultipartFile file) {
        List<Map<String, String>> list = EasyExcelImportUtils.makeData(file, null, 0, 1);
        List<Map<String, String>> dataAccessoryList = EasyExcelImportUtils.makeData(file, null, 1, 1);
        return Result.success(sysAccountingProjectService.updateBatch(list, dataAccessoryList));
    }
}
